namespace Foo.SyntacticAnalysis
{
    public partial interface ISyntaxTreeNode : global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>
    {
        global::ParserGenerator.Input.SourceContext Context { get; set; }
    }

    [global::System.Serializable]
    public enum LexicalExpressionCategory
    {
        Empty,
        String,
        QuoteString,
        CharClass,
        NameReference,
        Kleene,
        Optional,
        Positive,
        Repeat,
        Concat,
        Union,
    }

    [global::System.Serializable]
    public abstract partial class LexicalExpression : global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        public abstract global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag { get; }
        public bool IsEmpty => this is global::Foo.SyntacticAnalysis.EmptyLexicalExpression;
        public bool IsString => this is global::Foo.SyntacticAnalysis.StringLexicalExpression;
        public bool IsQuoteString => this is global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression;
        public bool IsCharClass => this is global::Foo.SyntacticAnalysis.CharClassLexicalExpression;
        public bool IsNameReference => this is global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression;
        public bool IsKleene => this is global::Foo.SyntacticAnalysis.KleeneLexicalExpression;
        public bool IsOptional => this is global::Foo.SyntacticAnalysis.OptionalLexicalExpression;
        public bool IsPositive => this is global::Foo.SyntacticAnalysis.PositiveLexicalExpression;
        public bool IsRepeat => this is global::Foo.SyntacticAnalysis.RepeatLexicalExpression;
        public bool IsConcat => this is global::Foo.SyntacticAnalysis.ConcatLexicalExpression;
        public bool IsUnion => this is global::Foo.SyntacticAnalysis.UnionLexicalExpression;
        public global::Foo.SyntacticAnalysis.EmptyLexicalExpression AsEmpty => (global::Foo.SyntacticAnalysis.EmptyLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.StringLexicalExpression AsString => (global::Foo.SyntacticAnalysis.StringLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression AsQuoteString => (global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.CharClassLexicalExpression AsCharClass => (global::Foo.SyntacticAnalysis.CharClassLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression AsNameReference => (global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.KleeneLexicalExpression AsKleene => (global::Foo.SyntacticAnalysis.KleeneLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.OptionalLexicalExpression AsOptional => (global::Foo.SyntacticAnalysis.OptionalLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.PositiveLexicalExpression AsPositive => (global::Foo.SyntacticAnalysis.PositiveLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.RepeatLexicalExpression AsRepeat => (global::Foo.SyntacticAnalysis.RepeatLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.ConcatLexicalExpression AsConcat => (global::Foo.SyntacticAnalysis.ConcatLexicalExpression)this;
        public global::Foo.SyntacticAnalysis.UnionLexicalExpression AsUnion => (global::Foo.SyntacticAnalysis.UnionLexicalExpression)this;

        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        internal LexicalExpression(global::ParserGenerator.Input.SourceContext context = null)
        {
            Context = context;
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewEmpty(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::Foo.SyntacticAnalysis.EmptyLexicalExpression(context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewString(string value, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::Foo.SyntacticAnalysis.StringLexicalExpression(value, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewQuoteString(string value, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression(value, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewCharClass(char value, global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::Foo.SyntacticAnalysis.CharClassLexicalExpression(value, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewNameReference(string name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression(name, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewKleene(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.KleeneLexicalExpression(operand, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewOptional(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.OptionalLexicalExpression(operand, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewPositive(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.PositiveLexicalExpression(operand, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewRepeat(global::Foo.SyntacticAnalysis.LexicalExpression operand, int? minCount = null, int? maxCount = null, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            if (minCount < 0)
                throw new global::System.ArgumentOutOfRangeException(nameof(minCount), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(minCount)));
            if (maxCount < 0)
                throw new global::System.ArgumentOutOfRangeException(nameof(maxCount), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(maxCount)));
            return new global::Foo.SyntacticAnalysis.RepeatLexicalExpression(operand, minCount, maxCount, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewConcat(global::Foo.SyntacticAnalysis.LexicalExpression left, global::Foo.SyntacticAnalysis.LexicalExpression right, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::Foo.SyntacticAnalysis.ConcatLexicalExpression(left, right, context);
        }

        public static global::Foo.SyntacticAnalysis.LexicalExpression NewUnion(global::Foo.SyntacticAnalysis.LexicalExpression left, global::Foo.SyntacticAnalysis.LexicalExpression right, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::Foo.SyntacticAnalysis.UnionLexicalExpression(left, right, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            throw new global::System.NotImplementedException();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::Foo.SyntacticAnalysis.ISyntaxTreeNode)this).GetEnumerator();
        public abstract void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v);
        public abstract void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d);
        public abstract void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v);

        public string ToString(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteLexicalExpression(this, w, d);
                return writer.ToString().Trim();
            }
        }

        public string ToString(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            return ToString(v, -1);
        }

        public sealed override string ToString()
        {
            return ToString(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class EmptyLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.Empty;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 0;

        internal EmptyLexicalExpression(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::Foo.SyntacticAnalysis.EmptyLexicalExpression New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::Foo.SyntacticAnalysis.EmptyLexicalExpression(context);
        }

        public global::Foo.SyntacticAnalysis.EmptyLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.EmptyLexicalExpression(Context);
        }

        public global::Foo.SyntacticAnalysis.EmptyLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.EmptyLexicalExpression(context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessEmptyLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteEmptyLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkEmptyLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class StringLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public string Value { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.String;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 0;

        internal StringLexicalExpression(string value, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            Value = value;
        }

        public static global::Foo.SyntacticAnalysis.StringLexicalExpression New(string value, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::Foo.SyntacticAnalysis.StringLexicalExpression(value, context);
        }

        public global::Foo.SyntacticAnalysis.StringLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.StringLexicalExpression(Value, Context);
        }

        public global::Foo.SyntacticAnalysis.StringLexicalExpression WithValue(string value)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::Foo.SyntacticAnalysis.StringLexicalExpression(value, Context);
        }

        public global::Foo.SyntacticAnalysis.StringLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.StringLexicalExpression(Value, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessStringLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteStringLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkStringLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class QuoteStringLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public string Value { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.QuoteString;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 0;

        internal QuoteStringLexicalExpression(string value, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            Value = value;
        }

        public static global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression New(string value, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression(value, context);
        }

        public global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression(Value, Context);
        }

        public global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression WithValue(string value)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression(value, Context);
        }

        public global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression(Value, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessQuoteStringLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteQuoteStringLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkQuoteStringLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class CharClassLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public char Value { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.CharClass;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 0;

        internal CharClassLexicalExpression(char value, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            Value = value;
        }

        public static global::Foo.SyntacticAnalysis.CharClassLexicalExpression New(char value, global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::Foo.SyntacticAnalysis.CharClassLexicalExpression(value, context);
        }

        public global::Foo.SyntacticAnalysis.CharClassLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.CharClassLexicalExpression(Value, Context);
        }

        public global::Foo.SyntacticAnalysis.CharClassLexicalExpression WithValue(char value)
        {
            return new global::Foo.SyntacticAnalysis.CharClassLexicalExpression(value, Context);
        }

        public global::Foo.SyntacticAnalysis.CharClassLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.CharClassLexicalExpression(Value, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessCharClassLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteCharClassLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkCharClassLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class NameReferenceLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public string Name { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.NameReference;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 0;

        internal NameReferenceLexicalExpression(string name, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            Name = name;
        }

        public static global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression New(string name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression(name, context);
        }

        public global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression(Name, Context);
        }

        public global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression WithName(string name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression(name, Context);
        }

        public global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression(Name, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessNameReferenceLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteNameReferenceLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkNameReferenceLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class KleeneLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public global::Foo.SyntacticAnalysis.LexicalExpression Operand { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.Kleene;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 1;

        internal KleeneLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            Operand = operand;
        }

        public static global::Foo.SyntacticAnalysis.KleeneLexicalExpression New(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.KleeneLexicalExpression(operand, context);
        }

        public global::Foo.SyntacticAnalysis.KleeneLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.KleeneLexicalExpression(Operand, Context);
        }

        public global::Foo.SyntacticAnalysis.KleeneLexicalExpression WithOperand(global::Foo.SyntacticAnalysis.LexicalExpression operand)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.KleeneLexicalExpression(operand, Context);
        }

        public global::Foo.SyntacticAnalysis.KleeneLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.KleeneLexicalExpression(Operand, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Operand;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Operand;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessKleeneLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteKleeneLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkKleeneLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class OptionalLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public global::Foo.SyntacticAnalysis.LexicalExpression Operand { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.Optional;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 1;

        internal OptionalLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            Operand = operand;
        }

        public static global::Foo.SyntacticAnalysis.OptionalLexicalExpression New(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.OptionalLexicalExpression(operand, context);
        }

        public global::Foo.SyntacticAnalysis.OptionalLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.OptionalLexicalExpression(Operand, Context);
        }

        public global::Foo.SyntacticAnalysis.OptionalLexicalExpression WithOperand(global::Foo.SyntacticAnalysis.LexicalExpression operand)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.OptionalLexicalExpression(operand, Context);
        }

        public global::Foo.SyntacticAnalysis.OptionalLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.OptionalLexicalExpression(Operand, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Operand;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Operand;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessOptionalLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteOptionalLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkOptionalLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class PositiveLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public global::Foo.SyntacticAnalysis.LexicalExpression Operand { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.Positive;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 1;

        internal PositiveLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            Operand = operand;
        }

        public static global::Foo.SyntacticAnalysis.PositiveLexicalExpression New(global::Foo.SyntacticAnalysis.LexicalExpression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.PositiveLexicalExpression(operand, context);
        }

        public global::Foo.SyntacticAnalysis.PositiveLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.PositiveLexicalExpression(Operand, Context);
        }

        public global::Foo.SyntacticAnalysis.PositiveLexicalExpression WithOperand(global::Foo.SyntacticAnalysis.LexicalExpression operand)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.PositiveLexicalExpression(operand, Context);
        }

        public global::Foo.SyntacticAnalysis.PositiveLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.PositiveLexicalExpression(Operand, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Operand;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Operand;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessPositiveLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WritePositiveLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkPositiveLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class RepeatLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public global::Foo.SyntacticAnalysis.LexicalExpression Operand { get; }
        public int? MinCount { get; }
        public int? MaxCount { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.Repeat;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 1;

        internal RepeatLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression operand, int? minCount = null, int? maxCount = null, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            if (minCount < 0)
                throw new global::System.ArgumentOutOfRangeException(nameof(minCount), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(minCount)));
            if (maxCount < 0)
                throw new global::System.ArgumentOutOfRangeException(nameof(maxCount), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(maxCount)));
            Operand = operand;
            MinCount = minCount;
            MaxCount = maxCount;
        }

        public static global::Foo.SyntacticAnalysis.RepeatLexicalExpression New(global::Foo.SyntacticAnalysis.LexicalExpression operand, int? minCount = null, int? maxCount = null, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            if (minCount < 0)
                throw new global::System.ArgumentOutOfRangeException(nameof(minCount), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(minCount)));
            if (maxCount < 0)
                throw new global::System.ArgumentOutOfRangeException(nameof(maxCount), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(maxCount)));
            return new global::Foo.SyntacticAnalysis.RepeatLexicalExpression(operand, minCount, maxCount, context);
        }

        public global::Foo.SyntacticAnalysis.RepeatLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.RepeatLexicalExpression(Operand, MinCount, MaxCount, Context);
        }

        public global::Foo.SyntacticAnalysis.RepeatLexicalExpression WithOperand(global::Foo.SyntacticAnalysis.LexicalExpression operand)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::Foo.SyntacticAnalysis.RepeatLexicalExpression(operand, MinCount, MaxCount, Context);
        }

        public global::Foo.SyntacticAnalysis.RepeatLexicalExpression WithMinCount(int? minCount)
        {
            if (minCount < 0)
                throw new global::System.ArgumentOutOfRangeException(nameof(minCount), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(minCount)));
            return new global::Foo.SyntacticAnalysis.RepeatLexicalExpression(Operand, minCount, MaxCount, Context);
        }

        public global::Foo.SyntacticAnalysis.RepeatLexicalExpression WithMaxCount(int? maxCount)
        {
            if (maxCount < 0)
                throw new global::System.ArgumentOutOfRangeException(nameof(maxCount), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(maxCount)));
            return new global::Foo.SyntacticAnalysis.RepeatLexicalExpression(Operand, MinCount, maxCount, Context);
        }

        public global::Foo.SyntacticAnalysis.RepeatLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.RepeatLexicalExpression(Operand, MinCount, MaxCount, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Operand;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Operand;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessRepeatLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteRepeatLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkRepeatLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class ConcatLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public global::Foo.SyntacticAnalysis.LexicalExpression Left { get; }
        public global::Foo.SyntacticAnalysis.LexicalExpression Right { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.Concat;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 2;

        internal ConcatLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression left, global::Foo.SyntacticAnalysis.LexicalExpression right, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            Left = left;
            Right = right;
        }

        public static global::Foo.SyntacticAnalysis.ConcatLexicalExpression New(global::Foo.SyntacticAnalysis.LexicalExpression left, global::Foo.SyntacticAnalysis.LexicalExpression right, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::Foo.SyntacticAnalysis.ConcatLexicalExpression(left, right, context);
        }

        public global::Foo.SyntacticAnalysis.ConcatLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.ConcatLexicalExpression(Left, Right, Context);
        }

        public global::Foo.SyntacticAnalysis.ConcatLexicalExpression WithLeft(global::Foo.SyntacticAnalysis.LexicalExpression left)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            return new global::Foo.SyntacticAnalysis.ConcatLexicalExpression(left, Right, Context);
        }

        public global::Foo.SyntacticAnalysis.ConcatLexicalExpression WithRight(global::Foo.SyntacticAnalysis.LexicalExpression right)
        {
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::Foo.SyntacticAnalysis.ConcatLexicalExpression(Left, right, Context);
        }

        public global::Foo.SyntacticAnalysis.ConcatLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.ConcatLexicalExpression(Left, Right, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Left;
                    case 1:
                        return Right;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Left;
            yield return Right;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessConcatLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteConcatLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkConcatLexicalExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class UnionLexicalExpression : global::Foo.SyntacticAnalysis.LexicalExpression, global::Foo.SyntacticAnalysis.ISyntaxTreeNode
    {
        public global::Foo.SyntacticAnalysis.LexicalExpression Left { get; }
        public global::Foo.SyntacticAnalysis.LexicalExpression Right { get; }
        public sealed override global::Foo.SyntacticAnalysis.LexicalExpressionCategory Tag => global::Foo.SyntacticAnalysis.LexicalExpressionCategory.Union;
        int global::System.Collections.Generic.IReadOnlyCollection<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.Count => 2;

        internal UnionLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression left, global::Foo.SyntacticAnalysis.LexicalExpression right, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            Left = left;
            Right = right;
        }

        public static global::Foo.SyntacticAnalysis.UnionLexicalExpression New(global::Foo.SyntacticAnalysis.LexicalExpression left, global::Foo.SyntacticAnalysis.LexicalExpression right, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::Foo.SyntacticAnalysis.UnionLexicalExpression(left, right, context);
        }

        public global::Foo.SyntacticAnalysis.UnionLexicalExpression Copy()
        {
            return new global::Foo.SyntacticAnalysis.UnionLexicalExpression(Left, Right, Context);
        }

        public global::Foo.SyntacticAnalysis.UnionLexicalExpression WithLeft(global::Foo.SyntacticAnalysis.LexicalExpression left)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            return new global::Foo.SyntacticAnalysis.UnionLexicalExpression(left, Right, Context);
        }

        public global::Foo.SyntacticAnalysis.UnionLexicalExpression WithRight(global::Foo.SyntacticAnalysis.LexicalExpression right)
        {
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::Foo.SyntacticAnalysis.UnionLexicalExpression(Left, right, Context);
        }

        public global::Foo.SyntacticAnalysis.UnionLexicalExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::Foo.SyntacticAnalysis.UnionLexicalExpression(Left, Right, context);
        }

        global::Foo.SyntacticAnalysis.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Left;
                    case 1:
                        return Right;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::Foo.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::Foo.SyntacticAnalysis.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::Foo.SyntacticAnalysis.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Left;
            yield return Right;
        }

        public sealed override void AcceptCharClassCollector(global::Foo.SyntacticAnalysis.ICharClassCollector v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.ProcessUnionLexicalExpression(this);
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteUnionLexicalExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::Foo.SyntacticAnalysis.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkUnionLexicalExpression(this);
        }
    }

    public partial interface ICharClassCollector
    {
        void ProcessLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression n);
        void ProcessEmptyLexicalExpression(global::Foo.SyntacticAnalysis.EmptyLexicalExpression n);
        void ProcessStringLexicalExpression(global::Foo.SyntacticAnalysis.StringLexicalExpression n);
        void ProcessQuoteStringLexicalExpression(global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression n);
        void ProcessCharClassLexicalExpression(global::Foo.SyntacticAnalysis.CharClassLexicalExpression n);
        void ProcessNameReferenceLexicalExpression(global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression n);
        void ProcessKleeneLexicalExpression(global::Foo.SyntacticAnalysis.KleeneLexicalExpression n);
        void ProcessOptionalLexicalExpression(global::Foo.SyntacticAnalysis.OptionalLexicalExpression n);
        void ProcessPositiveLexicalExpression(global::Foo.SyntacticAnalysis.PositiveLexicalExpression n);
        void ProcessRepeatLexicalExpression(global::Foo.SyntacticAnalysis.RepeatLexicalExpression n);
        void ProcessConcatLexicalExpression(global::Foo.SyntacticAnalysis.ConcatLexicalExpression n);
        void ProcessUnionLexicalExpression(global::Foo.SyntacticAnalysis.UnionLexicalExpression n);
    }

    public partial interface ISyntaxTreeNodeWriter
    {
        void WriteLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteEmptyLexicalExpression(global::Foo.SyntacticAnalysis.EmptyLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteEmptyLexicalExpression(global::Foo.SyntacticAnalysis.EmptyLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteStringLexicalExpression(global::Foo.SyntacticAnalysis.StringLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteStringLexicalExpression(global::Foo.SyntacticAnalysis.StringLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteQuoteStringLexicalExpression(global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteQuoteStringLexicalExpression(global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteCharClassLexicalExpression(global::Foo.SyntacticAnalysis.CharClassLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteCharClassLexicalExpression(global::Foo.SyntacticAnalysis.CharClassLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteNameReferenceLexicalExpression(global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteNameReferenceLexicalExpression(global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteKleeneLexicalExpression(global::Foo.SyntacticAnalysis.KleeneLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteKleeneLexicalExpression(global::Foo.SyntacticAnalysis.KleeneLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteOptionalLexicalExpression(global::Foo.SyntacticAnalysis.OptionalLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteOptionalLexicalExpression(global::Foo.SyntacticAnalysis.OptionalLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WritePositiveLexicalExpression(global::Foo.SyntacticAnalysis.PositiveLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WritePositiveLexicalExpression(global::Foo.SyntacticAnalysis.PositiveLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteRepeatLexicalExpression(global::Foo.SyntacticAnalysis.RepeatLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteRepeatLexicalExpression(global::Foo.SyntacticAnalysis.RepeatLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteConcatLexicalExpression(global::Foo.SyntacticAnalysis.ConcatLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteConcatLexicalExpression(global::Foo.SyntacticAnalysis.ConcatLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteUnionLexicalExpression(global::Foo.SyntacticAnalysis.UnionLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteUnionLexicalExpression(global::Foo.SyntacticAnalysis.UnionLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
    }

    [global::System.Serializable]
    public partial class SyntaxTreeNodeWriter : global::Foo.SyntacticAnalysis.ISyntaxTreeNodeWriter
    {
        public static global::Foo.SyntacticAnalysis.SyntaxTreeNodeWriter Instance { get; } = new global::Foo.SyntacticAnalysis.SyntaxTreeNodeWriter();

        public virtual void WriteLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteLexicalExpression(n, writer, -1);
        }

        public virtual void WriteLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            n.AcceptSyntaxTreeNodeWriter(this, writer, d);
        }

        public virtual void WriteEmptyLexicalExpression(global::Foo.SyntacticAnalysis.EmptyLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteEmptyLexicalExpression(n, writer, -1);
        }

        public virtual void WriteStringLexicalExpression(global::Foo.SyntacticAnalysis.StringLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteStringLexicalExpression(n, writer, -1);
        }

        public virtual void WriteQuoteStringLexicalExpression(global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteQuoteStringLexicalExpression(n, writer, -1);
        }

        public virtual void WriteCharClassLexicalExpression(global::Foo.SyntacticAnalysis.CharClassLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteCharClassLexicalExpression(n, writer, -1);
        }

        public virtual void WriteNameReferenceLexicalExpression(global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteNameReferenceLexicalExpression(n, writer, -1);
        }

        public virtual void WriteKleeneLexicalExpression(global::Foo.SyntacticAnalysis.KleeneLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteKleeneLexicalExpression(n, writer, -1);
        }

        public virtual void WriteOptionalLexicalExpression(global::Foo.SyntacticAnalysis.OptionalLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteOptionalLexicalExpression(n, writer, -1);
        }

        public virtual void WritePositiveLexicalExpression(global::Foo.SyntacticAnalysis.PositiveLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WritePositiveLexicalExpression(n, writer, -1);
        }

        public virtual void WriteRepeatLexicalExpression(global::Foo.SyntacticAnalysis.RepeatLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteRepeatLexicalExpression(n, writer, -1);
        }

        public virtual void WriteConcatLexicalExpression(global::Foo.SyntacticAnalysis.ConcatLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteConcatLexicalExpression(n, writer, -1);
        }

        public virtual void WriteUnionLexicalExpression(global::Foo.SyntacticAnalysis.UnionLexicalExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteUnionLexicalExpression(n, writer, -1);
        }
    }

    [global::System.Serializable]
    public partial class SyntaxTreeNodeWalker
    {
        public virtual void WalkLexicalExpression(global::Foo.SyntacticAnalysis.LexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            n.AcceptSyntaxTreeNodeWalker(this);
        }

        public virtual void EnterEmptyLexicalExpression(global::Foo.SyntacticAnalysis.EmptyLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveEmptyLexicalExpression(global::Foo.SyntacticAnalysis.EmptyLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkEmptyLexicalExpression(global::Foo.SyntacticAnalysis.EmptyLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterEmptyLexicalExpression(n);
            LeaveEmptyLexicalExpression(n);
        }

        public virtual void EnterStringLexicalExpression(global::Foo.SyntacticAnalysis.StringLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveStringLexicalExpression(global::Foo.SyntacticAnalysis.StringLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkStringLexicalExpression(global::Foo.SyntacticAnalysis.StringLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterStringLexicalExpression(n);
            LeaveStringLexicalExpression(n);
        }

        public virtual void EnterQuoteStringLexicalExpression(global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveQuoteStringLexicalExpression(global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkQuoteStringLexicalExpression(global::Foo.SyntacticAnalysis.QuoteStringLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterQuoteStringLexicalExpression(n);
            LeaveQuoteStringLexicalExpression(n);
        }

        public virtual void EnterCharClassLexicalExpression(global::Foo.SyntacticAnalysis.CharClassLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveCharClassLexicalExpression(global::Foo.SyntacticAnalysis.CharClassLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkCharClassLexicalExpression(global::Foo.SyntacticAnalysis.CharClassLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterCharClassLexicalExpression(n);
            LeaveCharClassLexicalExpression(n);
        }

        public virtual void EnterNameReferenceLexicalExpression(global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveNameReferenceLexicalExpression(global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkNameReferenceLexicalExpression(global::Foo.SyntacticAnalysis.NameReferenceLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterNameReferenceLexicalExpression(n);
            LeaveNameReferenceLexicalExpression(n);
        }

        public virtual void EnterKleeneLexicalExpression(global::Foo.SyntacticAnalysis.KleeneLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveKleeneLexicalExpression(global::Foo.SyntacticAnalysis.KleeneLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkKleeneLexicalExpression(global::Foo.SyntacticAnalysis.KleeneLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterKleeneLexicalExpression(n);
            WalkLexicalExpression(n.Operand);
            LeaveKleeneLexicalExpression(n);
        }

        public virtual void EnterOptionalLexicalExpression(global::Foo.SyntacticAnalysis.OptionalLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveOptionalLexicalExpression(global::Foo.SyntacticAnalysis.OptionalLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkOptionalLexicalExpression(global::Foo.SyntacticAnalysis.OptionalLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterOptionalLexicalExpression(n);
            WalkLexicalExpression(n.Operand);
            LeaveOptionalLexicalExpression(n);
        }

        public virtual void EnterPositiveLexicalExpression(global::Foo.SyntacticAnalysis.PositiveLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeavePositiveLexicalExpression(global::Foo.SyntacticAnalysis.PositiveLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkPositiveLexicalExpression(global::Foo.SyntacticAnalysis.PositiveLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterPositiveLexicalExpression(n);
            WalkLexicalExpression(n.Operand);
            LeavePositiveLexicalExpression(n);
        }

        public virtual void EnterRepeatLexicalExpression(global::Foo.SyntacticAnalysis.RepeatLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveRepeatLexicalExpression(global::Foo.SyntacticAnalysis.RepeatLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkRepeatLexicalExpression(global::Foo.SyntacticAnalysis.RepeatLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterRepeatLexicalExpression(n);
            WalkLexicalExpression(n.Operand);
            LeaveRepeatLexicalExpression(n);
        }

        public virtual void EnterConcatLexicalExpression(global::Foo.SyntacticAnalysis.ConcatLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveConcatLexicalExpression(global::Foo.SyntacticAnalysis.ConcatLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkConcatLexicalExpression(global::Foo.SyntacticAnalysis.ConcatLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterConcatLexicalExpression(n);
            WalkLexicalExpression(n.Left);
            WalkLexicalExpression(n.Right);
            LeaveConcatLexicalExpression(n);
        }

        public virtual void EnterUnionLexicalExpression(global::Foo.SyntacticAnalysis.UnionLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveUnionLexicalExpression(global::Foo.SyntacticAnalysis.UnionLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkUnionLexicalExpression(global::Foo.SyntacticAnalysis.UnionLexicalExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterUnionLexicalExpression(n);
            WalkLexicalExpression(n.Left);
            WalkLexicalExpression(n.Right);
            LeaveUnionLexicalExpression(n);
        }
    }
}
